#include "ListTextBox.h"


ListTextBox::ListTextBox(SDL_Surface* screen){
	this->screen = screen;	
}

ListTextBox::ListTextBox(SDL_Surface* screen, int showOpts, int x, int y, int w, int h, LISTSTR* optNames) {
	this->screen = screen;
	this->opciones = optNames;
	this->cantCajas = showOpts;
	for (int i=0; i<(cantCajas); i++)
		this->cajas[i] = new Textbox(this->screen, x, y+(i*h), w, h);
	//Fill the textboxes with the first elements of options.
	if (this->opciones->size() >= this->cantCajas) {
		LISTSTR::iterator it = this->opciones->begin();
		for (int i= 0; i<(cantCajas);i++){
			this->cajas[i]->setText(*it);
			it++;
		}
		this->selectorPrimero.opcionActual = this->opciones->begin();
		this->selectorUltimo.opcionActual = this->opciones->begin();
		for (int j=0; j<(cantCajas-1); j++)
			this->selectorUltimo.opcionActual++;
		this->selectorUltimo.numCaj = (cantCajas-1);
		this->selectorActual.opcionActual =this->opciones->begin();
		this->selectorActual.numCaj = 0;
	} else {
		LISTSTR::iterator it = this->opciones->begin();
		for (int i= 0; i < this->opciones->size(); i++){
			this->cajas[i]->setText(*it);
			it++;
		}
		this->selectorUltimo.numCaj=(this->opciones->size()-1);
		this->selectorPrimero.opcionActual = this->opciones->begin();
		it= this->opciones->end();
		it--;
		this->selectorUltimo.opcionActual = it;
		this->selectorActual.opcionActual =this->opciones->begin();
		this->selectorActual.numCaj = 0;
	}
	this->selectorPrimero.numCaj = 0;
	this->cajas[0]->setSelected(true);
}


void ListTextBox::addOption(std::string opt){
	this->opciones->push_back(opt);
	if(this->opciones->size() == 1){
		this->selectorActual.opcionActual = this->opciones->begin();
		this->selectorPrimero.opcionActual = this->opciones->begin();
		this->selectorUltimo.opcionActual = this->opciones->begin();
	}
	//If not empty nor full , update last selector.
	if(this->opciones->size() <= (this->cantCajas) && this->opciones->size()>1 ) {
		this->selectorUltimo.opcionActual++;
		this->selectorUltimo.numCaj++;
	}
	this->cajas[this->selectorUltimo.numCaj]->setText(*this->selectorUltimo.opcionActual);
}

std::string  ListTextBox::deleteOption(){
	std::string borrado = "";
	if(!this->opciones->empty())
		borrado = *this->selectorActual.opcionActual;
	if (this->opciones->size() > 1){
		//Delete first box
		if (this->selectorActual.opcionActual == this->opciones->begin()){
			this->selectorPrimero.opcionActual++;
			this->selectorActual.opcionActual++;
			for (int f=0;f<(cantCajas-1);f++)
				this->cajas[f]->setText(this->cajas[f+1]->getText());
			this->opciones->pop_front();
			if(this->opciones->size() >= this->cantCajas)
				this->selectorUltimo.opcionActual++;
			else{
				this->cajas[this->selectorUltimo.numCaj]->clearBox();
				this->selectorUltimo.numCaj--;
			}
		}else{
			//Delete intermediate boxes
			LISTSTR::iterator erase = this->selectorActual.opcionActual;
			if (this->selectorActual.opcionActual != this->selectorUltimo.opcionActual){
				//If box 1 selected scrollup to perform a "last box erase", if box 2 just 1 scrollup
				if(this->selectorActual.numCaj == 1){
					this->scrollUp();
					this->scrollUp();
				}else{
					this->scrollUp();
				}
				this->selectorActual.opcionActual++;
				if(this->opciones->size() > this->cantCajas  )
					this->selectorUltimo.opcionActual++;
				else {
					this->cajas[this->selectorUltimo.numCaj]->clearBox();
					this->selectorUltimo.numCaj--;
				}
				this->opciones->erase(erase);
			} else {
				//Delete last box with option.
				if(this->opciones->size() > this->cantCajas){
					LISTSTR::iterator end = this->opciones->end();
					end--;
					if(this->selectorActual.opcionActual != end){
						this->selectorUltimo.opcionActual++;
						this->selectorActual.opcionActual++;
					}else{
						this->scrollUp();
					}
				} else {
					this->selectorUltimo.opcionActual--;
					this->selectorActual.opcionActual--;
					this->cajas[this->selectorUltimo.numCaj]->clearBox();
					this->cajas[this->selectorActual.numCaj]->setSelected(false);
					this->selectorUltimo.numCaj--;
					this->selectorActual.numCaj--;
					this->cajas[this->selectorActual.numCaj]->setSelected(true);

				}
				this->opciones->erase(erase);				
			}
		}	
	}else{
		if (!this->opciones->empty()){
			this->opciones->pop_front();
			this->cajas[this->selectorUltimo.numCaj]->clearBox();
			this->selectorActual.opcionActual = this->opciones->begin();
			this->selectorPrimero.opcionActual = this->opciones->begin();
			this->selectorUltimo.opcionActual = this->opciones->begin();	
		}
	}
	return borrado;
}


ListTextBox::ListTextBox(SDL_Surface* screen, int showOpts, int x, int y, int w, int h) {
	this->screen = screen;
	this->opciones = new LISTSTR();
	this->selectorPrimero.opcionActual = this->opciones->begin();
	this->selectorUltimo.opcionActual = this->opciones->begin();
	this->selectorActual.opcionActual =this->opciones->begin();
	this->cantCajas = showOpts;
	for (int i=0; i<cantCajas; i++)
		this->cajas[i] = new Textbox(this->screen, x, y+(i*h), w, h);
	this->cajas[0]->setSelected(true);
	this->selectorActual.numCaj = 0;
	this->selectorUltimo.numCaj = 0;
	this->selectorPrimero.numCaj = 0;

}

void ListTextBox::handleEvent(SDL_Event* event){
	Uint8* teclas;
	std::list<std::string>::iterator end(this->opciones->end());
	if (!this->opciones->empty()){
	--end;
	};
	teclas = SDL_GetKeyState(NULL); 
	if (teclas[SDLK_UP]) { 
		if(this->selectorActual.opcionActual !=this->opciones->begin()){
			if(this->selectorActual.opcionActual != this->selectorPrimero.opcionActual){
				this->cajas[this->selectorActual.numCaj]->setSelected(false);
				this->selectorActual.opcionActual--;
				this->selectorActual.numCaj--;
				this->cajas[this->selectorActual.numCaj]->setSelected(true);
			} else {
				//Cambiar lista
				for (int f=(cantCajas-1);f>0;f--)
					this->cajas[f]->setText(this->cajas[f-1]->getText());
				this->selectorPrimero.opcionActual--;
				this->selectorUltimo.opcionActual--;
				this->selectorActual.opcionActual--;
				this->cajas[this->selectorActual.numCaj]->setText(*this->selectorActual.opcionActual);
			}
		}

	}
	if (teclas[SDLK_DOWN]) { 
		if(this->selectorActual.opcionActual != end) {
			if(this->selectorActual.opcionActual != this->selectorUltimo.opcionActual){
				this->cajas[this->selectorActual.numCaj]->setSelected(false);
				this->selectorActual.opcionActual++;
				this->selectorActual.numCaj++;
				this->cajas[this->selectorActual.numCaj]->setSelected(true);
			}else{
				//Cambiar lista
				for (int f=0;f<(cantCajas-1);f++)
					this->cajas[f]->setText(this->cajas[f+1]->getText());
				this->selectorPrimero.opcionActual++;
				this->selectorUltimo.opcionActual++;
				this->selectorActual.opcionActual++;
				this->cajas[this->selectorActual.numCaj]->setText(*this->selectorActual.opcionActual);			
			}
		}
	}
	if(event->type == SDL_MOUSEBUTTONDOWN && event->button.button == SDL_BUTTON_LEFT){
		for(int i=0;i<this->cantCajas;i++){
			if(this->cajas[i]->isClicked(event) && this->cajas[i]->getText().length() > 0 && i != this->selectorActual.numCaj){
				int cajSelec = this->selectorActual.numCaj;
				this->selectorActual.numCaj = i;
				this->cajas[cajSelec]->setSelected(false);
				this->cajas[i]->setSelected(true);
				int diff = i - cajSelec;
				if (diff > 0){
					for (int j =0 ;j < diff;j++)
						this->selectorActual.opcionActual++;				
				} else {
					diff = diff* -1;
					for (int j =0 ;j<diff;j++)
						this->selectorActual.opcionActual--;			
				}
			}	
		}
	}
}


void ListTextBox::draw(){
	if(!this->opciones->empty()){
		this->cajas[this->selectorPrimero.numCaj]->setText(*this->selectorPrimero.opcionActual);
		this->cajas[this->selectorActual.numCaj]->setText(*this->selectorActual.opcionActual);
		this->cajas[this->selectorUltimo.numCaj]->setText(*this->selectorUltimo.opcionActual);
	}
	for (int i=0; i<cantCajas; i++){
		this->cajas[i]->drawBox(); // draw the box
		this->cajas[i]->drawText();
	}
}

void ListTextBox::scrollUp(){
	if ((this->opciones->size()>cantCajas) && (this->selectorPrimero.opcionActual != this->opciones->begin())) {
		for (int f=(cantCajas-1);f>0;f--)
			this->cajas[f]->setText(this->cajas[f-1]->getText());
		this->selectorPrimero.opcionActual--;
		this->selectorUltimo.opcionActual--;
		if (this->selectorActual.numCaj != (cantCajas-1)){
			this->cajas[this->selectorActual.numCaj]->setSelected(false);
			this->selectorActual.numCaj++;
			this->cajas[this->selectorActual.numCaj]->setSelected(true);
		} else {
			this->selectorActual.opcionActual--;
		}
		this->cajas[0]->setText(*this->selectorPrimero.opcionActual);
	}

}

void ListTextBox::scrollDown(){
	std::list<std::string>::iterator end(this->opciones->end());
	if(!this->opciones->empty())
		--end;
	//Verify if theres something to scroll on.
	if ((this->opciones->size()>cantCajas) && (this->selectorUltimo.opcionActual != end)) {
		
		for (int f=0;f<(cantCajas-1);f++)
			this->cajas[f]->setText(this->cajas[f+1]->getText());
		this->selectorPrimero.opcionActual++;
		this->selectorUltimo.opcionActual++;
		if (this->selectorActual.numCaj != 0){
			this->cajas[this->selectorActual.numCaj]->setSelected(false);
			this->selectorActual.numCaj--;
			this->cajas[this->selectorActual.numCaj]->setSelected(true);
		} else {
			this->selectorActual.opcionActual++;
		}
		
		this->cajas[cantCajas-1]->setText(*this->selectorUltimo.opcionActual);
	}
}

ListTextBox::~ListTextBox(void) {

}
